package itsm.isperp.module.service.app;

import itsm.isperp.framework.core.context.ContextHolder;
import itsm.isperp.framework.message.domain.MessageType;
import itsm.isperp.framework.service.BaseService;
import itsm.isperp.framework.utils.HibernateUUIDGenerator;
import itsm.isperp.framework.utils.JsonBuilder;
import itsm.isperp.framework.web.request.JqGridFilterRuleOp;
import itsm.isperp.framework.web.request.JqGridRequest;
import itsm.isperp.module.entity.app.AppMessage;
import itsm.isperp.module.entity.app.AppMessageSender;
import itsm.isperp.module.entity.app.AppMessageSuccess;
import itsm.isperp.module.entity.app.AppUser;
import itsm.isperp.module.repository.app.AppMessageSenderMapper;
import itsm.isperp.module.repository.app.AppMessageSuccessMapper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baidu.yun.channel.auth.ChannelKeyPair;
import com.baidu.yun.channel.client.BaiduChannelClient;
import com.baidu.yun.channel.exception.ChannelClientException;
import com.baidu.yun.channel.exception.ChannelServerException;
import com.baidu.yun.channel.model.PushUnicastMessageRequest;
import com.baidu.yun.channel.model.PushUnicastMessageResponse;
import com.baidu.yun.core.log.YunLogEvent;
import com.baidu.yun.core.log.YunLogHandler;

/**
 * 系统消息发送服务
 * 
 * @author lizx
 * 
 */
@Service
public class AppMessageSenderService extends BaseService<AppMessageSender> {

	Logger logger = LoggerFactory.getLogger(AppMessageSenderService.class);

	@Autowired
	protected AppMessageSenderMapper appMessageSenderMapper;

	@Autowired
	protected AppMessageService appMessageService;

	@Autowired
	AppMessageSuccessMapper appMessageSuccessMapper;

	@Override
	public AppMessageSenderMapper getRepository() {
		return this.appMessageSenderMapper;
	}

	/**
	 * 发送内部消息
	 * 
	 * @param message
	 *            消息体
	 */
	public void sendTo(AppMessage message) {
		AppUserService appUserService = ContextHolder
				.getSpringBean("appUserService");

		// 在发送前，需要将消息推送到百度
		AppMessageSuccess ms = new AppMessageSuccess(message);
		ms.setId(HibernateUUIDGenerator.generate());
		appMessageSuccessMapper.save(ms);

		if (MessageType.MSG.equals(ms.getMessageType())) {
			// 使用百度将消息推送
			Map<String, Object> info = appUserService.findPushInfoByName(ms
					.getReceiver());
			String userId = (String) info.get("user_id");

			if (StringUtils.isNotEmpty(userId)) {
				// 1.key设置
				String apiKey = ContextHolder.getConfigByKey("baiduPushApiKey");
				String secretKey = ContextHolder
						.getConfigByKey("baiduPushSecretKey");
				ChannelKeyPair pair = new ChannelKeyPair(apiKey, secretKey);

				// 2. 创建BaiduChannelClient对象实例
				BaiduChannelClient channelClient = new BaiduChannelClient(pair);

				// 3. 若要了解交互细节，请注册YunLogHandler类
				channelClient.setChannelLogHandler(new YunLogHandler() {
					@Override
					public void onHandle(YunLogEvent event) {
					}
				});

				try {

					// 4. 创建请求类对象
					// 手机端的ChannelId， 手机端的UserId， 先用1111111111111代替，用户需替换为自己的
					PushUnicastMessageRequest request = new PushUnicastMessageRequest();
					int device_type = 0;
					try {
						device_type = Integer.valueOf((String) info
								.get("device_type"));

					} catch (Exception e) {
						device_type = 3;
					}
					request.setDeviceType(device_type); // device_type => 1: web
														// 2: pc 3:android 4:ios
														// 5:wp

					// 获取用户的channelid
					if (info.get("channel_id") != null) {
						request.setChannelId(Long.valueOf(info
								.get("channel_id").toString()));
					}
					request.setUserId(userId);
					Map<String, Object> map = new HashMap<String, Object>();
					if (device_type == 4) {
						request.setMessageType(1);
						request.setDeployStatus(2);
						map.put("aps", "");

					} else {
						map.put("id", ms.getId());
						map.put("title", ms.getTitle());
						map.put("content", ms.getContent());
						map.put("senderId", ms.getSenderId());
						map.put("sourceId", ms.getSourceId());
						map.put("receiverId", ms.getReceiverId());
					}
					request.setMessage(JsonBuilder.buildNonNullBinder().toJson(
							map));
					// 5. 调用pushMessage接口
					PushUnicastMessageResponse response = channelClient
							.pushUnicastMessage(request);

					// 6. 认证推送成功
				} catch (ChannelClientException e) {
					// 处理客户端错误异常
					logger.error(e.toString(), e);
				} catch (ChannelServerException e) {
					// 处理服务端错误异常
					logger.error(String
							.format("request_id: %d, error_code: %d, error_message: %s",
									e.getRequestId(), e.getErrorCode(),
									e.getErrorMsg()));
				}
			}

		}

	}

	/**
	 * 发送消息
	 * 
	 * @param sender
	 */
	public void sendTo(AppMessageSender sender) {

		String[] receiverIds = sender.getReceiverId().split(",");
		String[] sendTypes = sender.getMessageType().split(",");
		int len = receiverIds.length;
		int tLen = sendTypes.length;

		List<AppMessage> messages = new ArrayList<>();

		for (int i = 0; i < len; i++) {
			for (int j = 0; j < tLen; j++) {

				String type = sendTypes[j];
				AppMessage message = new AppMessage();
				message.setContent(sender.getContent());
				message.setMessageLevel(1);
				message.setSenderId(ContextHolder.getLoginUsername());
				message.setTitle(sender.getTitle());
				message.setSender(message.getSenderId());
				message.setMessageType(type);
				message.setSourceId(sender.getSourceId());
				message.setReceiverId(receiverIds[i]);
				if (MessageType.EMAIL.equals(type)) {

					AppUserService appUserService = ContextHolder
							.getSpringBean(AppUserService.class);
					AppUser u = appUserService.findByUsername(receiverIds[i]);

					message.setReceiverAddress(u.getEmail());
					// add to query
					messages.add(message);
				} else if (MessageType.SMS.equals(type)) {
					AppUserService appUserService = ContextHolder
							.getSpringBean(AppUserService.class);
					AppUser u = appUserService.findByUsername(receiverIds[i]);

					message.setReceiverAddress(u.getMobile());
					// add to query
					messages.add(message);
				} else {
					this.sendTo(message);
				}

			}
		}

		this.appMessageService.addToMessageQuery(messages);

		this.getRepository().save(sender);
	}

	public int findAllCount(String username) {
		JqGridRequest req = new JqGridRequest();
		req.isPageable(false);
		req.setSelectColumns(" count(*) as count_t");
		req.addFilterRule("sender_id", JqGridFilterRuleOp.eq, username);
		Map<String, Object> map = this.appMessageSenderMapper
				.findAllDetailByRequest(req).get(0);
		return Integer.parseInt(map.get("count_t").toString());
	}
}
